/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "mbox_proc.h"
#include "firewall_platform.h"
#include <port_pinmap.h>

#include "Platform_Types.h"

uint8_t mbox_proc_id_to_master_id(uint8_t proc_id)
{
    uint8_t master_id = 0xFFU;

    switch (proc_id) {
        case MBOX_PROC_ID_CR52P0:
            master_id =  MBOX_MASTER_ID_CR52P0;
            break;
        case MBOX_PROC_ID_CR52P1:
            master_id =  MBOX_MASTER_ID_CR52P1;
            break;
        case MBOX_PROC_ID_CR52P2:
            master_id =  MBOX_MASTER_ID_CR52P2;
            break;
        case MBOX_PROC_ID_CR52P3:
            master_id =  MBOX_MASTER_ID_CR52P3;
            break;
        case MBOX_PROC_ID_CR52P4:
            master_id =  MBOX_MASTER_ID_CR52P4;
            break;
        case MBOX_PROC_ID_CR52P5:
            master_id =  MBOX_MASTER_ID_CR52P5;
            break;
        case MBOX_PROC_ID_CR52P6:
            master_id =  MBOX_MASTER_ID_CR52P6;
            break;
        case MBOX_PROC_ID_CR52P7:
            master_id =  MBOX_MASTER_ID_CR52P7;
            break;
        case MBOX_PROC_ID_CR5LP:
            master_id =  MBOX_MASTER_ID_CR5LP;
            break;
        case MBOX_PROC_ID_CR5SE:
            master_id =  MBOX_MASTER_ID_CR5SE;
            break;
        default:
            break;
    }

    return master_id;
}

uint8_t Firewall_MpcGetRegionMaxNum(uint16_t baseOffset)
{
    uint8_t regionMaxNum;
    /* #10 Get the maximum number of the memory port. */
    switch (baseOffset)
    {
        /* The maximum number of regions in RAM port are same. */
        case FIREWALL_MPC_RAMC1_ADDR_OFFSET:
        case FIREWALL_MPC_RAMC2_ADDR_OFFSET:
        case FIREWALL_MPC_RAMC3_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_IRAMC_MAXREGION;
            break;
        }
        case FIREWALL_MPC_RAM_LP_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_IRAM_LP_MAXREGION;
            break;
        }
        /* The maximum number of regions in XSPI port are same. */
        case FIREWALL_MPC_XSPI1A_ADDR_OFFSET:
        case FIREWALL_MPC_XSPI1B_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_XSPI_MAXREGION;
            break;
        }
        case FIREWALL_MPC_MB_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_MB_MAXREGION;
            break;
        }
        /* The maximum number of regions in VIC port are same. */
        case FIREWALL_MPC_VIC1_ADDR_OFFSET:
        case FIREWALL_MPC_VIC2_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_VIC_MAXREGION;
            break;
        }
        /* The maximum number of regions in MRAM port are same. */
        case FIREWALL_MPC_MRAM1_ADDR_OFFSET:
        case FIREWALL_MPC_MRAM2_ADDR_OFFSET:
        case FIREWALL_MPC_MRAM3_ADDR_OFFSET:
        case FIREWALL_MPC_MRAM4_ADDR_OFFSET:
        case FIREWALL_MPC_MRAM5_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_MRAM_MAXREGION;
            break;
        }
        /* The maximum number of regions in CR5 CACHE/TCM port are same. */
        case FIREWALL_MPC_CR5LP_ADDR_OFFSET:
        case FIREWALL_MPC_CR5SE_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_CR5_MAXREGION;
            break;
        }
        case FIREWALL_MPC_R52TCM_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_R52_TCM_MAXREGION;
            break;
        }
        case FIREWALL_MPC_SEIP_ADDR_OFFSET:
        {
            regionMaxNum = FIREWALL_MPC_SEIP_MAXREGION;
            break;
        }
        default:
        {
            regionMaxNum = 0U;
            break;
        }
    }

    return regionMaxNum;
}

/**
 * @brief Get the maximum number of peripherals for the apbmux.
 *
 * This function get the maximum number of peripherals in the specified apbmux.
 *
 * @param[in] ppcApbmuxId the id of the apbmux.
 *
 *  @return The maximum number of peripherals for the apbmux.
 */
uint16_t Firewall_PpcGetApbmuxIpMaxnum(uint8_t ppcApbmuxId)
{
    uint16_t ip_maxnum;

    /* #10 Get the maximum number of peripherals in the specified apbmux. */
    switch (ppcApbmuxId)
    {
        case 0:
        {
            ip_maxnum = FIREWALL_PPC_APBMUX1_IP_MAXNUM;
            break;
        }
        case 1:
        {
            ip_maxnum = FIREWALL_PPC_APBMUX2_IP_MAXNUM;
            break;
        }
        case 2:
        {
            ip_maxnum = FIREWALL_PPC_APBMUX3_IP_MAXNUM;
            break;
        }
        case 3:
        {
            ip_maxnum = FIREWALL_PPC_APBMUX4_IP_MAXNUM;
            break;
        }
        case 4:
        {
            ip_maxnum = FIREWALL_PPC_APBMUX5_IP_MAXNUM;
            break;
        }
        case 5:
        {
            ip_maxnum = FIREWALL_PPC_APBMUX6_IP_MAXNUM;
            break;
        }
        case 6:
        {
            ip_maxnum = FIREWALL_PPC_APBMUX7_IP_MAXNUM;
            break;
        }
        case 7:
        {
            ip_maxnum = FIREWALL_PPC_APBMUX8_IP_MAXNUM;
            break;
        }
        default:
        {
            ip_maxnum = 0U;
            break;
        }
    }

    return ip_maxnum;
}

/**
 * @brief Get the base address of the gpio controller.
 *
 * @param[in] channelId The id of the pin channel.
 * @param[in] gpio_Base The base address of the gpio controller.
 *
 * @return The result of this function.
 * @details - return FIREWALL_E_OK : Get the specified gpio base address success.
 *          - return FIREWALL_E_GPIO_channelId : The id of the pin channel is unvalid.
 */
uint8_t Firewall_DioGetChannelInfo(uint32_t channelId,
                                    uint32_t *dioIndex, uint32_t *dioBase)
{
    uint8_t ret_val = 0;
    uint8_t i;
    uint8_t size;
    const Port_PinMapType *matchPtr;

    /* #10 Check the parameters. */
    if ((NULL == dioIndex) && (NULL == dioBase))
    {
        ret_val = 1;
    }
    else if (FIREWALL_GPIO_CHANNEL_MAXNUM <= channelId)
    {
        ret_val = 1;
    }
    else
    {
        matchPtr = &Port_GpioMaps[0];
        size = sizeof(Port_GpioMaps) / sizeof(Port_GpioMaps[0]);

        for (i = 0U; i < size; i++)
        {
            if ((channelId >= matchPtr->pinStart) &&
                (channelId < (matchPtr->pinStart + matchPtr->pinNum)))
            {
                break;
            }

            matchPtr++;
        }

        if (i != size)
        {
            if (NULL != dioIndex)
            {
                *dioIndex = channelId - matchPtr->pinStart + matchPtr->ctrlIdx;
            }
            if (NULL != dioBase)
            {
                *dioBase = matchPtr->ctrlBase;
            }
        }
    }

    return ret_val;
}
